from datetime import datetime

from django.template import Context, loader
from django.http import HttpResponse
from django.core.paginator import Paginator, InvalidPage, EmptyPage

from stock.models import *
from pandas import *
from lib.ta import *

from stock.simulation.account import Account

def showList(request):
    latestDate = StockPrice.objects.only('Date').latest('Date').Date
    stocklist = StockPrice.objects.all().filter(Date=latestDate).order_by('Name')
    t = loader.get_template('stock/list.html')
    c = Context({
      'latestDate' : latestDate,
      'stocklist': stocklist,
    })
    return HttpResponse(t.render(c))
    
def showChart(request,quote):
    stockData = StockPrice.objects.all().filter(Name=quote).order_by('-Date')[:500]
    stockPrice = DataFrame([price.getQuoteDict() for price in reversed(stockData)])

    stockPrice = EMA(stockPrice,22)
    stockPrice = EMA(stockPrice,60)
    stockPrice = MACD(stockPrice,12,26,9)
    stockPrice = ADX(stockPrice,14,14)
    
    fieldList = [i.lower() for i in stockPrice]
    stockPrice = [stockPrice.xs(i).fillna('Null').to_dict() for i in range(stockPrice.index[-1]+1)]
    t = loader.get_template('stock/chart.html')
    c = Context({
      'quote' : quote,
      'stockprice': stockPrice,
      'fieldList': fieldList,
    })
    return HttpResponse(t.render(c))

def showSimulation(request):
    #quoteList = ['ADVANC','DTAC','BANPU','BIGC','JAS','MCS','BBL']
    
    # SET 100
    #quoteList = ['ADVANC','AJ','AMATA','AOT','AP','ASP','BANPU','BAY','BBL','BCP','BEC','BECL','BGH','BH','BIGC','BJC','BLA','BLAND','BTS','CENTEL','CK','CPALL','CPF','CPN','DCC','DELTA','DTAC','EGCO','ESSO','GFPT','GLOBAL','GLOW','GSTEEL','GUNKUL','HANA','HEMRAJ','HMPRO','IRPC','ITD','IVL','JAS','KBANK','KBS','KH','KK','KSL','KTB','LANNA','LH','LHBANK','LOXLEY','LPN','MAJOR','MAKRO','MCOT','MCS','MINT','PHATRA','PS','PSL','PTL','PTT','PTTEP','PTTGC','QH','RATCH','ROBINS','SAMART','SAMTEL','SAT','SC','SCB','SCC','SCCC','SF','SGP','SIRI','SMT','SPALI','SSI','STA','STEC','STPI','SVI','TASCO','TCAP','THAI','THCOM','TICON','TISCO','TMB','TOP','TPC','TPIPL','TRUE','TTA','TTCL','TTW','TUF','TVO']
    
    # SET 50
    quoteList = ['ADVANC','AOT','BANPU','BAY','BBL','BCP','BEC','BGH','BH','BIGC','BJC','BLA','BTS','CPALL','CPF','CPN','DCC','DELTA','DTAC','EGCO','ESSO','GLOW','HMPRO','IRPC','IVL','KBANK','KTB','LH','MAKRO','MINT','PS','PTT','PTTEP','PTTGC','RATCH','ROBINS','SCB','SCC','SCCC','SPALI','STA','TCAP','THAI','TISCO','TMB','TOP','TPC','TPIPL','TRUE','TUF']
    
    
    stockPrice = {}
    indexSize = {}
    maxSize = 0
    lastPrice = {}
    
    for quote in quoteList:
      lastPrice[quote] = 0
      stockData = StockPrice.objects.all().filter(Name=quote).filter(Date__gt=datetime(2009, 1, 1)).order_by('-Date')
      print "Build ",quote,
      stockPrice[quote] = DataFrame([price.getQuoteDict() for price in reversed(stockData)])    
      stockPrice[quote] = EMA(stockPrice[quote],10)        
      stockPrice[quote] = EMA(stockPrice[quote],30)
      stockPrice[quote] = EMA(stockPrice[quote],60)
      #stockPrice[quote] = MACD(stockPrice[quote],12,26,9)
      #stockPrice[quote] = ADX(stockPrice[quote],14,14)   
      indexSize[quote] = stockPrice[quote].index[-1]
      if indexSize[quote] > maxSize :
        maxSize = indexSize[quote]
      print " - Complete " , indexSize[quote]
        

    quoteList = [quote for quote in quoteList if indexSize[quote] == maxSize]
    
    account = Account(1000000)
    margin = 100000
    accountMatrix = []
    
    i = 30
    while i < maxSize :
      i = i + 1
      date = None
      event = ""
      for quote in quoteList:
        currentdate = stockPrice[quote].get_value(i, 'Date')
        # buy #################################
        if (stockPrice[quote].get_value(i, 'ema10') > stockPrice[quote].get_value(i, 'ema60')) and (stockPrice[quote].get_value(i-1, 'ema10') <= stockPrice[quote].get_value(i-1, 'ema60')):
            cash = account.cash
            stock_price = stockPrice[quote].get_value(i, 'Close')
            if cash > margin :
              stock_share = int(margin/stock_price)
              order = {'Date': currentdate,
                       'quote': quote,
                       'side': 'buy',
                       'price': stock_price,
                       'share': stock_share}
              event = event + "Buy [" + quote + "] : " + str(stock_share) + " at " + str(stock_price) + " THB"
              account.execute(order)
              
        # sell ##################################
        
        if (stockPrice[quote].get_value(i, 'ema10') < stockPrice[quote].get_value(i, 'ema30')) and (stockPrice[quote].get_value(i-1, 'ema10') >= stockPrice[quote].get_value(i-1, 'ema30')):
            cash = account.cash
            stock_price = stockPrice[quote].get_value(i, 'Close')
            stock_share = account.getHoldingSharebyQuote(quote)
            if stock_share > 0 :
              
              
              order = {'Date': currentdate,
                       'quote': quote,
                       'side': 'sell',
                       'price': stock_price,
                       'share': stock_share}
              event = event + "Sell [" + quote + "] : " + str(stock_share) + " at " + str(stock_price) + " THB"
              account.execute(order)   
        
        # update price ###########################
        lastPrice[quote] = stockPrice[quote].get_value(i, 'Close')
           
      # update account value ##########################
      account.updatePrice(lastPrice)
      
      accountMatrix.append({ 'Date':currentdate,
                             'cash':account.getCash() + account.getHoldingCost(),
                             'hold':account.getHoldingValue(),
                             'total':account.getTotalValue(),
                             'event':event
                            })
        
    #print account.orderHistory
    #print account.holdings


    t = loader.get_template('stock/sim.html')
    c = Context({
      'quoteList':quoteList,
      'stockprice': stockPrice,
      'account': account,
      'accountMatrix': accountMatrix,
    })
    return HttpResponse(t.render(c))
    
def showPrice(request,quote):
    stockprice_list = StockPrice.objects.all().filter(Name=quote).order_by('-Date')
    paginator = Paginator(stockprice_list, 25) # Show 25 price per page

    # Make sure page request is an int. If not, deliver first page.
    try:
        page = int(request.GET.get('page', '1'))
    except ValueError:
        page = 1

    # If page request (9999) is out of range, deliver last page of results.
    try:
        stockprice = paginator.page(page)
    except (EmptyPage, InvalidPage):
        stockprice = paginator.page(paginator.num_pages)
    
    t = loader.get_template('stock/price.html')
    c = Context({
      'quote' : quote,
      'stockprice': stockprice,
    })
    return HttpResponse(t.render(c))
